package com.smart.community.commons.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.smart.community.commons.handler.MyBatisPlusMetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 数据库自动配置类
 * @author Wu.Liang
 * @since 2024-12-19
 * @version 1.0.0
 */
@Slf4j
@Configuration
public class DatabaseAutoConfiguration {
    
    /**
     * MyBatis-Plus拦截器
     * 
     * @return MyBatis-Plus拦截器
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass(name = "com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor")
    @ConditionalOnProperty(name = "spring.datasource.url")
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        try {
            log.info("🔧 初始化MyBatis-Plus拦截器...");
            
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            
            // 乐观锁插件
            OptimisticLockerInnerInterceptor optimisticLockerInterceptor = new OptimisticLockerInnerInterceptor();
            interceptor.addInnerInterceptor(optimisticLockerInterceptor);
            
            // 分页插件
            PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
            paginationInterceptor.setMaxLimit(1000L);
            paginationInterceptor.setOverflow(false);
            interceptor.addInnerInterceptor(paginationInterceptor);
            
            log.info("✅ MyBatis-Plus拦截器初始化完成，已配置乐观锁和分页插件");
            return interceptor;
        } catch (Exception e) {
            log.warn("MyBatis-Plus拦截器初始化失败，可能是缺少相关依赖: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * MyBatis-Plus元数据处理器
     * 
     * @return MyBatis-Plus元数据处理器
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass(name = "com.baomidou.mybatisplus.core.handlers.MetaObjectHandler")
    public MetaObjectHandler metaObjectHandler() {
        try {
            log.info("🔧 初始化MyBatis-Plus元数据处理器...");
            
            MyBatisPlusMetaObjectHandler metaObjectHandler = new MyBatisPlusMetaObjectHandler();
            
            log.info("✅ MyBatis-Plus元数据处理器初始化完成");
            return metaObjectHandler;
        } catch (Exception e) {
            log.warn("MyBatis-Plus元数据处理器初始化失败，可能是缺少相关依赖: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * 数据库连接池配置
     * 
     * @return 数据库连接池配置
     */
    @Bean
    @ConditionalOnMissingBean
    public DatabaseConnectionPoolConfig databaseConnectionPoolConfig() {
        log.info("🔧 初始化数据库连接池配置...");
        
        DatabaseConnectionPoolConfig config = new DatabaseConnectionPoolConfig();
        
        log.info("✅ 数据库连接池配置初始化完成");
        return config;
    }
    
    /**
     * 数据库连接池配置类
     */
    public static class DatabaseConnectionPoolConfig {
        
        /**
         * 最大连接数
         */
        private int maximumPoolSize = 20;
        
        /**
         * 最小空闲连接数
         */
        private int minimumIdle = 5;
        
        /**
         * 连接超时时间（毫秒）
         */
        private long connectionTimeout = 30000;
        
        /**
         * 空闲超时时间（毫秒）
         */
        private long idleTimeout = 300000;
        
        /**
         * 连接最大生存时间（毫秒）
         */
        private long maxLifetime = 1200000;
        
        /**
         * 验证超时时间（毫秒）
         */
        private long validationTimeout = 5000;
        
        /**
         * 连接测试查询
         */
        private String connectionTestQuery = "SELECT 1";
        
        /**
         * 泄漏检测阈值（毫秒）
         */
        private long leakDetectionThreshold = 60000;
        
        // Getters and Setters
        public int getMaximumPoolSize() { return maximumPoolSize; }
        public void setMaximumPoolSize(int maximumPoolSize) { this.maximumPoolSize = maximumPoolSize; }
        
        public int getMinimumIdle() { return minimumIdle; }
        public void setMinimumIdle(int minimumIdle) { this.minimumIdle = minimumIdle; }
        
        public long getConnectionTimeout() { return connectionTimeout; }
        public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
        
        public long getIdleTimeout() { return idleTimeout; }
        public void setIdleTimeout(long idleTimeout) { this.idleTimeout = idleTimeout; }
        
        public long getMaxLifetime() { return maxLifetime; }
        public void setMaxLifetime(long maxLifetime) { this.maxLifetime = maxLifetime; }
        
        public long getValidationTimeout() { return validationTimeout; }
        public void setValidationTimeout(long validationTimeout) { this.validationTimeout = validationTimeout; }
        
        public String getConnectionTestQuery() { return connectionTestQuery; }
        public void setConnectionTestQuery(String connectionTestQuery) { this.connectionTestQuery = connectionTestQuery; }
        
        public long getLeakDetectionThreshold() { return leakDetectionThreshold; }
        public void setLeakDetectionThreshold(long leakDetectionThreshold) { this.leakDetectionThreshold = leakDetectionThreshold; }
        
        @Override
        public String toString() {
            return String.format("DatabaseConnectionPoolConfig{maximumPoolSize=%d, minimumIdle=%d, connectionTimeout=%d, idleTimeout=%d, maxLifetime=%d}",
                    maximumPoolSize, minimumIdle, connectionTimeout, idleTimeout, maxLifetime);
        }
    }
}
